package com.example.demo;

import org.springframework.boot.loader.JarLauncher;
import org.springframework.boot.loader.LaunchedURLClassLoader;
import org.springframework.boot.loader.archive.Archive;
import org.springframework.boot.loader.jar.JarFile;

import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public class CustomJarLauncher extends JarLauncher {

    static ThreadLocal<URLClassLoader> middleWareClassloaderThreadLocal = new ThreadLocal<>();

    @Override
    protected List<Archive> getClassPathArchives() throws Exception {
        return super.getClassPathArchives();
    }


    public static void main(String[] args) throws Exception {
        new CustomJarLauncher().launch(args);
    }


    @Override
    protected void launch(String[] args) throws Exception {
        JarFile.registerUrlProtocolHandler();
        List<Archive> classPathArchives = getClassPathArchives();
        /**
         * 从这里面找出中间件的jar包
         */
        List<URL> allURLs = classPathArchives.stream().map(entries -> {
            try {
                return entries.getUrl();
            } catch (MalformedURLException e) {
                return null;
            }
        }).filter(Objects::nonNull).collect(Collectors.toList());


        List<URL> middleWareClassPathArchives = new ArrayList<>();
        for (URL url : allURLs) {
            String urlPath = url.getPath();
            if (urlPath == null) {
                continue;
            }
            boolean isMiddleWareJar = urlPath.contains("common-v1")
                    || urlPath.contains("middle-ware");
            if (isMiddleWareJar) {
                if (urlPath.contains("middle-ware-api")) {
                    continue;
                }
                middleWareClassPathArchives.add(url);
            }
        }


        /**
         * 从lib目录，移除中间件需要的jar包，但是，中间件的api不能移除
         */
        allURLs.removeAll(middleWareClassPathArchives);


        CustomLaunchedURLClassLoader loader =
                new CustomLaunchedURLClassLoader(allURLs.toArray(new URL[0]),
                getClass().getClassLoader());
        loader.setMiddleWareClassPathArchives(middleWareClassPathArchives);

        launch(args, getMainClass(), loader);
    }

}
